
#include <rtdef.h>
#include <rtthread.h>
#include <rthw.h>

#include "PRINT/my_printf.h"

#include "LED/led.h"
#include "UART/uart.h"
#include "PLL/pll.h"
#include "PRINT/my_printf.h"
#include "VIC/vic_reg.h"
#include "INIT/init.h"
#include "EXTI/exti.h"
#include "TIMER/timer.h"
#include "SDIO/sdio.h"
#include "PUBLIC/test.h"
#include "PUBLIC/public.h"

int flag1;
int flag2;
int flag3;

struct rt_thread rt_flag1_thread;
struct rt_thread rt_flag2_thread;
struct rt_thread rt_flag3_thread;

rt_uint8_t rt_flag1_thread_stack[2048];
rt_uint8_t rt_flag2_thread_stack[2048];
rt_uint8_t rt_flag3_thread_stack[512];

extern rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];
extern u32 PendSV_Handler;
extern rt_uint32_t rt_thread_switch_interrupt_flag;
extern rt_uint32_t rt_interrupt_to_thread;

extern rt_tick_t rt_tick;

void delay(int t){
    for(; t != 0; t--);
}

void flag1_thread_entry(void *p_arg){
    printf("flag1_thread_entry %d\r\n", rt_tick);
    for(; ; ) {
        led1_on();
        printf("led1_on %c\r\n", ' ');
        rt_thread_delay(50);
        led1_off();
        printf("led1_off %c\r\n", ' ');
        rt_thread_delay(50);
    }
}

void flag2_thread_entry(void *p_arg){
    printf("flag2_thread_entry %d\r\n", rt_tick);
    for(; ; ) {
        led2_on();
        printf("led2_on %c\r\n", ' ');
        rt_thread_delay(100);
        led2_off();
        printf("led2_off %d\r\n", rt_tick);
        rt_thread_delay(100);
    }
}

void flag3_thread_entry(void *p_arg){
    for(; ; ) {
        flag3 = 1;
        delay(100);
        flag3 = 0;
        delay(100);
        rt_schedule_3();
    }
}

void log(u32 r0, u32 r1){
    u32 fp, sp, lr, cpsr;

    __asm__(
        "mov %0, fp\n"
        "mov %1, sp\n"
        "mov %2, lr\n"
        "mrs %3, cpsr\n"
        :"=r"(fp), "=r"(sp), "=r"(lr), "=r"(cpsr)
    );
    printf("log fp:%x sp:%x lr:%x cpsr:%x\r\n", fp, sp, lr, cpsr);

}

void log_thread(struct rt_thread *r0){
    printf("%08x\r\n", (u32)r0->sp);
    printf("%08x\r\n", (u32)r0->stack_addr);
    printf("%08x\r\n", (u32)r0->stack_size);
    printf("%08x\r\n", (u32)r0->entry);
    printf("%08x\r\n", (u32)r0->parameter);
    printf("%08x\r\n", (u32)&r0->tlist);
}

void log_all(){
    u32 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, fp, r12, sp, lr, pc, cpsr;
    
    __asm__(
        "mov %0, r0\n"
        "mov %1, r1\n"
        "mov %2, r2\n"
        "mov %3, r3\n"
        "mov %4, r4\n"
        "mov %5, r5\n"
        "mov %6, r6\n"
        "mov %7, r7\n"
        "mov %8, r8\n"
        "mov %9, r9\n"
        :"=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6), "=r"(r7), "=r"(r8), "=r"(r9)
    );

    __asm__(
        "mov %0, r10\n"
        "mov %1, fp\n"
        "mov %2, r12\n"
        "mov %3, sp\n"
        "mov %4, lr\n"
        "mov %5, pc\n"
        "mrs %6, cpsr\n"
        :"=r"(r10), "=r"(fp), "=r"(r12), "=r"(sp), "=r"(lr), "=r"(pc), "=r"(cpsr)
    );


    printf("r0: %x r1: %x r2: %x r3: %x r4: %x r5: %x r6: %x r7: %x r8: %x r9: %x r10: %x fp: %x r12: %x sp: %x lr: %x pc: %x cpsr: %x\r\n",
            r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, fp, r12, sp, lr, pc, cpsr);
}

int main(){
    
    /* 关中断 */
    rt_hw_interrupt_disable();

    vic_init(63, (u32)&PendSV_Handler);
    led_init();
    // rt_tick = 0;
    printf("ok rtt %x %d\r\n", &rt_tick, rt_tick);
    
    /* 设置SysTick中断频率 */
    SysTick_Config();
    
    /* 初始化系统调度器 */
    rt_system_scheduler_init();

    printf("ok rt_system_scheduler_init %x %d\r\n", &rt_tick, rt_tick);
    
    /* 初始化空闲线程 */    
    rt_thread_idle_init();
    
    /* 初始化线程 */
    rt_thread_init( &rt_flag1_thread,
                    "rt_flag1_thread",                /* 线程名字，字符串形式 */
                    flag1_thread_entry,
                    RT_NULL,
                    &rt_flag1_thread_stack[0],
                    sizeof(rt_flag1_thread_stack) );
    
    rt_list_insert_before(&(rt_thread_priority_table[0]), &(rt_flag1_thread.tlist));
    
    rt_thread_init( &rt_flag2_thread,
                    "rt_flag2_thread",                /* 线程名字，字符串形式 */
                    flag2_thread_entry,
                    RT_NULL,
                    &rt_flag2_thread_stack[0],
                    sizeof(rt_flag2_thread_stack) );
    
    rt_list_insert_before(&(rt_thread_priority_table[1]), &(rt_flag2_thread.tlist));
    
    rt_thread_init( &rt_flag3_thread,
                    "rt_flag3_thread",                /* 线程名字，字符串形式 */
                    flag3_thread_entry,
                    RT_NULL,
                    &rt_flag3_thread_stack[0],
                    sizeof(rt_flag3_thread_stack) );
    
    rt_list_insert_before(&(rt_thread_priority_table[2]), &(rt_flag3_thread.tlist));

    printf("ok rt_list_insert_before %d\r\n", rt_tick);
    
    rt_system_scheduler_start();
    
    return 0;
}


void SysTick_Handler(void)
{
    /* 进入中断 */
    rt_interrupt_enter();

    rt_tick_increase();

    TINT_CSTAT |= (1 << 5); // 清除中断标志

    /* 离开中断 */
    rt_interrupt_leave();
}
